package com.chorye.mail.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chorye.mail.dao.MailMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chorye.mail.entity.Mail;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;


/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Chorye
 * @since 2018-12-25
 */
@Slf4j
@Service
public class MailService extends ServiceImpl<MailMapper, Mail> {

    @Autowired
    private MailMapper mailMapper;
    @Autowired
    private JavaMailSender mailSender;
    @Value("${mail.fromMail.addr}")
    private String from;

    /**
     * 发送简单邮件
     *
     * @param to      收件人
     * @param subject 主题
     * @param content 邮件内容
     */
    public void sendSimpleMail(String to, String subject, String content) {
        // 首先入库
        Mail mail = saveMail(to, subject, content, null, null, null);
        // 创建邮件内容
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);
        message.setTo(to);
        message.setSubject(subject);
        message.setText(content);

        try {
            mailSender.send(message);
            // 发送成功修改状态
            updateMail(mail);
            log.info("简单邮件已经发送。");
        } catch (Exception e) {
            log.error("发送简单邮件时出现异常。");
        }
    }


    /**
     * 发送html格式邮件
     *
     * @param to      收件人
     * @param subject 主题
     * @param content 邮件内容
     */
    public void sendHtmlMail(String to, String subject, String content) {
        // 首先入库
        Mail mail = saveMail(to, subject, content, null, null, null);
        // 创建邮件内容
        MimeMessage message = mailSender.createMimeMessage();
        try {
            // true表示需要创建一个multipart message
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);
            mailSender.send(message);
            // 发送成功修改状态
            updateMail(mail);
            log.info("html邮件发送成功");
        } catch (MessagingException e) {
            log.error("发送html邮件时发生异常！", e);
        }
    }

    /**
     * 发送带附件的邮件
     *
     * @param to        收件人
     * @param subject   主题
     * @param content   邮件内容
     * @param localPath 文件路径
     */
    public void sendAttachmentsMail(String to, String subject, String content, String localPath) {
        // 创建邮件内容
        MimeMessage message = mailSender.createMimeMessage();
        try {
            // true表示需要创建一个multipart message
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);
            // 读取文件
            FileSystemResource file = new FileSystemResource(new File(localPath));
            String fileName = localPath.substring(localPath.lastIndexOf(File.separator));
            // 此处省略将文件上传到文件服务器
            // TODO 上传后返回文件标识码
            String filePath = "";
            // 首先入库
            Mail mail = saveMail(to, subject, content, filePath, fileName, null);
            // 添加多个附件可以使用多条 helper.addAttachment(fileName, file)
            helper.addAttachment(fileName, file);
            mailSender.send(message);
            // 发送成功修改状态
            updateMail(mail);
            log.info("带附件的邮件已经发送。");
        } catch (MessagingException e) {
            log.error("发送带附件的邮件时发生异常！", e);
        }
    }

    /**
     * 发送带静态资源的邮件, 邮件中的静态资源一般就是指图片
     *
     * @param to      收件人
     * @param subject 主题
     * @param content 邮件内容
     * @param rscPath 图片路径
     * @param rscId   静态资源id
     */
    public void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId) {
        // 创建邮件内容
        MimeMessage message = mailSender.createMimeMessage();
        try {
            // true表示需要创建一个multipart message
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);
            // 读取文件
            FileSystemResource res = new FileSystemResource(new File(rscPath));
            helper.addInline(rscId, res);
            // 此处省略将文件上传到文件服务器
            // TODO 上传后返回文件标识码
            String filePath = "";
            // 首先入库
            Mail mail = saveMail(to, subject, content, filePath, null, rscId);
            // 添加多个附件可以使用多条 helper.addAttachment(fileName, file)
            mailSender.send(message);
            // 发送成功修改状态
            updateMail(mail);
            log.info("嵌入静态资源的邮件已经发送。");
        } catch (MessagingException e) {
            log.error("发送嵌入静态资源的邮件时发生异常！", e);
        }
    }

    /**
     * 发送模板邮件
     *
     * @param to      收件人
     * @param subject 主题
     * @param content 邮件内容
     */
    public void sendTemplateMail(String to, String subject, String content) {
        sendHtmlMail(to, subject, content);
    }

    /**
     * 邮件入库
     *
     * @param to         收件人
     * @param subject    主题
     * @param content    邮件内容
     * @param filePath   文件上传到文件服务器的路径
     * @param fileName   文件名称
     * @param resourceId 文件静态资源id，用于邮件显示图片
     * @return 插入后的邮件实体
     */
    private Mail saveMail(String to, String subject, String content, String filePath, String fileName, String resourceId) {
        Mail mail = new Mail();
        mail.setSendFrom(from);
        mail.setSendTo(to);
        mail.setMsg(content);
        mail.setMailSubject(subject);
        mail.setFilePath(filePath);
        mail.setFileName(fileName);
        mail.setResourceId(resourceId);
        // 初始化未成功
        mail.setSuccessFlag("1");
        mailMapper.insert(mail);
        return mail;
    }

    /**
     * 发送成功修改状态
     *
     * @param mail 邮件实体
     */
    private void updateMail(Mail mail) {
        QueryWrapper<Mail> condition = new QueryWrapper<>();
        condition.eq("id", mail.getId());
        // 修改为成功
        mail.setSuccessFlag("0");
        mailMapper.update(mail, condition);
    }
}
